package com.ice.framework.common.util;

import cn.hutool.core.exceptions.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author wangwei
 * @Date 2022/3/30 17:11
 */
@Slf4j
public class MiscUtil {

    public static final String COMMA = ",";

    public static final String SEMICOLON = ";";

    public static boolean isBaseType(Class<?> clazz) {
        if (clazz.isPrimitive()) {
            return true;
        } else {
            return clazz.getName().startsWith("java.lang.");
        }
    }

    /**
     * 判断是否为空
     */
    public static boolean isEmpty(Object object) {
        if (object == null) {
            return true;
        } else if (object instanceof String) {
            return "".equals(object.toString());
        } else if (object instanceof Collection) {
            return ((Collection) object).isEmpty();
        } else if (object instanceof Object[]) {
            return ((Object[]) ((Object[]) object)).length == 0;
        } else if (object instanceof Map) {
            return ((Map) object).isEmpty();
        } else {
            return false;
        }
    }

    public static boolean isNotEmpty(Object value) {
        return !isEmpty(value);
    }


    /**
     * 参数解码。当解码异常时，将返回输入参数
     */
    public static String decode(String value) {
        if (isEmpty(value)) {
            return value;
        }
        try {
            return URLDecoder.decode(value, "UTF-8");
        } catch (Exception e) {
            return value;
        }
    }

    /**
     * 参数URL编码，如果编码失败。将返回输入参数
     */
    public static String encode(String value) {
        if (isEmpty(value)) {
            return value;
        }
        try {
            return URLEncoder.encode(value, "UTF-8");
        } catch (Exception e) {
            return value;
        }
    }

    /**
     * 将字符串生成唯一longHash编码
     * @Author wangwei
     * @Date 2022/3/30
     */
    public static Long longHash(String str) {
        long h = 98764321261L;
        int l = str.length();
        char[] chars = str.toCharArray();

        for (int i = 0; i < l; i++) {
            h = 31 * h + chars[i];
        }
        return h;
    }

    /**
     * 休眠不抛异常
     * @param time
     */
    public static void sleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            log.warn("休眠异常：{}", ExceptionUtil.stacktraceToString(e));
        }
    }

    /**
     * 执行Consumer并将异常化解在内部.
     */
    public static final <T> boolean exeConsumer(Consumer<T> c, T t) {
        try {
            c.accept(t);
            return true;
        } catch (Exception e) {
            log.warn("t: {}, e: {}", t, ExceptionUtil.stacktraceToString(e));
            return false;
        }
    }

    /**
     * 执行Consumer并将异常化解在内部.
     */
    public static final <T> boolean exeConsumer(Consumer<T> c) {
        try {
            c.accept(null);
            return true;
        } catch (Exception e) {
            log.warn(" e: {}", ExceptionUtil.stacktraceToString(e));
            return false;
        }
    }

    /**
     * 执行Function并将异常化解在内部.
     */
    public static final <T, R> R exeFunction(Function<T, R> f, T t) {
        try {
            return f.apply(t);
        } catch (Exception e) {
            log.warn("{}", ExceptionUtil.stacktraceToString(e));
            return null;
        }
    }

    /**
     * 执行Supplier并将异常化解在内部.
     */
    public static final <T> T exeSupplier(Supplier<T> supplier) {
        try {
            return supplier.get();
        } catch (Exception e) {
            log.warn("{}", ExceptionUtil.stacktraceToString(e));
            return null;
        }
    }


    /**
     * 执行Runnable并将异常化解在内部.
     */
    public static final <T> void exeRunnable(Runnable runnable) {
        try {
            runnable.run();
        } catch (Exception e) {
            log.warn("{}", ExceptionUtil.stacktraceToString(e));
        }
    }
}
